switch (s->ioregsel) {
case IOAPIC_REG_VERSION:
result = ((((IOAPIC_NUM_PINS-1) & 0xff) << 16)
- | (IOAPIC_VERSION_ID & 0x0f));
+ | (IOAPIC_VERSION_ID & 0xff));
break;
#ifndef __ia64__
case IOAPIC_REG_ARB_ID:
/* XXX how arb_id used on p4? */
- result = ((s->id & 0xf) << 24);
+ result = ((s->arb_id & 0xf) << 24);
break;
#endif
(redir_content >> 32) & 0xffffffff :
redir_content & 0xffffffff;
} else {
- printk("upic_mem_readl:undefined ioregsel %x\n",
+ printk("apic_mem_readl:undefined ioregsel %x\n",
s->ioregsel);
domain_crash_synchronous();
}
if ((s->flags & IOAPIC_ENABLE_FLAG) &&
(addr >= s->base_address &&
- (addr <= s->base_address + IOAPIC_MEM_LENGTH)))
+ (addr < s->base_address + IOAPIC_MEM_LENGTH)))
return 1;
else
return 0;
else
HVM_DBG_LOG(DBG_LEVEL_IOAPIC,
"null round robin mask %x vector %x delivery_mode %x\n",
- deliver_bitmask, vector, deliver_bitmask);
+ deliver_bitmask, vector, dest_LowestPrio);
break;
}
ASSERT(s);
- for(i = 0; i < IOAPIC_NUM_PINS - 1; i++) {
+ for(i = 0; i < IOAPIC_NUM_PINS; i++) {
if (s->redirtbl[i].RedirForm.vector == vector)
return i;
}
result = find_highest_bit((unsigned long *)(vlapic->regs + APIC_IRR),
MAX_VECTOR);
- ASSERT( result == -1 || result > 16);
+ ASSERT( result == -1 || result >= 16);
return result;
}
result = find_highest_bit((unsigned long *)(vlapic->regs + APIC_ISR),
MAX_VECTOR);
- ASSERT( result == -1 || result > 16);
+ ASSERT( result == -1 || result >= 16);
return result;
}
}
else /* Logical */
{
- uint32_t ldr = vlapic_get_reg(target, APIC_LDR);
-
+ uint32_t ldr;
if ( target == NULL )
break;
+ ldr = vlapic_get_reg(target, APIC_LDR);
+
/* Flat mode */
if ( vlapic_get_reg(target, APIC_DFR) == APIC_DFR_FLAT)
{
if ( unlikely(vlapic == NULL || !vlapic_enabled(vlapic)) )
break;
- if ( test_and_set_bit(vector, vlapic->regs + APIC_IRR) )
+ if ( test_and_set_bit(vector, vlapic->regs + APIC_IRR) && trig_mode)
{
HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
- "level trig mode repeatedly for vector %d\n", vector);
+ "level trig mode repeatedly for vector %d\n", vector);
break;
}
- if ( level )
+ if ( trig_mode )
{
HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
"level trig mode for vector %d\n", vector);
break;
case APIC_DM_INIT:
- if ( level && !(trig_mode & APIC_INT_ASSERT) ) //Deassert
+ if ( trig_mode && !(level & APIC_INT_ASSERT) ) //Deassert
printk("This hvm_vlapic is for P4, no work for De-assert init\n");
else
{
return result;
}
+
/*
- This function is used by both ioapic and local APIC
- The bitmap is for vcpu_id
+ * This function is used by both ioapic and local APIC
+ * The bitmap is for vcpu_id
*/
-struct vlapic* apic_round_robin(struct domain *d,
+struct vlapic *apic_round_robin(struct domain *d,
uint8_t dest_mode,
uint8_t vector,
uint32_t bitmap)
/* the vcpu array is arranged according to vcpu_id */
do
{
- next++;
- if ( !d->vcpu[next] ||
- !test_bit(_VCPUF_initialised, &d->vcpu[next]->vcpu_flags) ||
- next == MAX_VIRT_CPUS )
+ if ( ++next == MAX_VIRT_CPUS )
next = 0;
+ if ( d->vcpu[next] == NULL ||
+ !test_bit(_VCPUF_initialised, &d->vcpu[next]->vcpu_flags) )
+ continue;
if ( test_bit(next, &bitmap) )
{
unsigned int dest = GET_APIC_DEST_FIELD(icr_high);
unsigned int short_hand = icr_low & APIC_SHORT_MASK;
- unsigned int trig_mode = icr_low & APIC_INT_ASSERT;
- unsigned int level = icr_low & APIC_INT_LEVELTRIG;
+ unsigned int trig_mode = icr_low & APIC_INT_LEVELTRIG;
+ unsigned int level = icr_low & APIC_INT_ASSERT;
unsigned int dest_mode = icr_low & APIC_DEST_MASK;
unsigned int delivery_mode = icr_low & APIC_MODE_MASK;
unsigned int vector = icr_low & APIC_VECTOR_MASK;
struct vlapic *target;
struct vcpu *v = NULL;
- uint32_t lpr_map;
+ uint32_t lpr_map=0;
HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "icr_high 0x%x, icr_low 0x%x, "
"short_hand 0x%x, dest 0x%x, trig_mode 0x%x, level 0x%x, "
{
do {
tmcct += vlapic_get_reg(vlapic, APIC_TMICT);
- } while ( tmcct < 0 );
+ } while ( tmcct <= 0 );
}
}
*result = vlapic_get_tmcct(vlapic);
break;
+ case APIC_ESR:
+ vlapic->err_write_count = 0;
+ *result = vlapic_get_reg(vlapic, offset);
+ break;
+
default:
*result = vlapic_get_reg(vlapic, offset);
break;
break;
case 2:
+ ASSERT( alignment != 3 );
result = *(unsigned short *)((unsigned char *)&tmp + alignment);
break;
case 4:
+ ASSERT( alignment == 0 );
result = *(unsigned int *)((unsigned char *)&tmp + alignment);
break;
unsigned int tmp;
unsigned char alignment;
- /* Some kernel do will access with byte/word alignment*/
+ /* Some kernels do will access with byte/word alignment */
printk("Notice: Local APIC write with len = %lx\n",len);
alignment = offset & 0x3;
tmp = vlapic_read(v, offset & ~0x3, 4);
/* XXX the saddr is a tmp variable from caller, so should be ok
But we should still change the following ref to val to
local variable later */
- val = (tmp & ~(0xff << alignment)) |
- ((val & 0xff) << alignment);
+ val = (tmp & ~(0xff << (8*alignment))) |
+ ((val & 0xff) << (8*alignment));
break;
case 2:
domain_crash_synchronous();
}
- val = (tmp & ~(0xffff << alignment)) |
- ((val & 0xffff) << alignment);
+ val = (tmp & ~(0xffff << (8*alignment))) |
+ ((val & 0xffff) << (8*alignment));
break;
case 3:
break;
case APIC_DFR:
- vlapic_set_reg(vlapic, APIC_DFR, val);
+ vlapic_set_reg(vlapic, APIC_DFR, val | 0x0FFFFFFF);
break;
case APIC_SPIV:
- vlapic_set_reg(vlapic, APIC_SPIV, val & 0x1ff);
+ vlapic_set_reg(vlapic, APIC_SPIV, val & 0x3ff);
if ( !( val & APIC_SPIV_APIC_ENABLED) )
{
for ( i = 0; i < VLAPIC_LVT_NUM; i++ )
{
- lvt_val = vlapic_get_reg(vlapic, APIC_LVT1 + 0x10 * i);
+ lvt_val = vlapic_get_reg(vlapic, APIC_LVTT + 0x10 * i);
vlapic_set_reg(vlapic, APIC_LVTT + 0x10 * i,
lvt_val | APIC_LVT_MASKED);
}
if ( vlapic_global_enabled(vlapic) &&
(addr >= vlapic->base_address) &&
- (addr <= vlapic->base_address + VLOCAL_APIC_MEM_LENGTH) )
+ (addr < vlapic->base_address + VLOCAL_APIC_MEM_LENGTH) )
return 1;
return 0;
case APIC_DM_NMI:
case APIC_DM_INIT:
case APIC_DM_STARTUP:
- vlapic->direct_intr.deliver_mode &= deliver_mode;
+ vlapic->direct_intr.deliver_mode &= (1 << (deliver_mode >> 8));
break;
default: